package fr.umlv.escapeir.structure;

import java.awt.Image;
import java.io.IOException;
import java.util.ArrayList;

import org.jbox2d.collision.shapes.CircleShape;
import org.jbox2d.collision.shapes.Shape;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.BodyType;
import org.jbox2d.dynamics.FixtureDef;

import fr.umlv.escapeir.GameWorld;
import fr.umlv.escapeir.gesture.Gesture;
import fr.umlv.escapeir.gesture.GestureListener;
import fr.umlv.escapeir.gesture.Type;
import fr.umlv.escapeir.painters.ImageLoader;
import fr.umlv.escapeir.painters.WorldGraphics2D;
import fr.umlv.escapeir.painters.WorldPainter;

public class Ship3 extends AbstractActor implements GestureListener {
	
	private static final int size = 10;
	private final BodyDef bdef;
	private Body body;
	private final FixtureDef fdef;
	private final ArrayList<CircleShape> shapes;
	private WorldPainter structPainter;
	private Behavior step;
	
	public Ship3 (float x, float y) throws ShipCreationException {
		bdef = new BodyDef();
		bdef.type = BodyType.DYNAMIC;
		bdef.position.set(x, y);
		
		final float halfsize = size/2;
		final float doublesize = size*2;
		
		CircleShape cshape0 = new CircleShape();
		cshape0.m_radius = size;
		cshape0.m_p.set(0,0);
		CircleShape cshape1 = new CircleShape();
		cshape1.m_radius = halfsize;
		cshape1.m_p.set(-doublesize,0);
		CircleShape cshape2 = new CircleShape();
		cshape2.m_radius = halfsize;
		cshape2.m_p.set(doublesize,0);
		
		shapes = new ArrayList<>();
		shapes.add(cshape0);
		shapes.add(cshape1);
		shapes.add(cshape2);
		
		fdef = new FixtureDef();
		fdef.restitution = 0;
		fdef.density = 0;
		
		try {
			structPainter = new WorldPainter() {
				final Image img = ImageLoader.load("fr/umlv/escapeir/painters/images/greenPulse.png");
				public void render(WorldGraphics2D painter) {
					painter.save();
					painter.translateFromWorld(getPosition());
					painter.rotate(getAngle());
					for (Shape shape: shapes)
						painter.drawShapeWithImage(shape, img);
					painter.restore();
				}
			};
		} catch (IOException e) {
			throw new ShipCreationException("Can't open image", e);
		}
		
		step = new Behavior () {
			private int tick = 0;
			private final int limit = 5*60;
			private boolean up = true;
			@Override
			public void apply() {
				if (tick < 0) return;
				if (tick == 0 && up)
					body.applyLinearImpulse(new Vec2(0,50), body.getWorldCenter());
				if (!up && tick <=limit/2 )
					body.setLinearVelocity(new Vec2(body.getLinearVelocity().x/2,body.getLinearVelocity().y/2));
				
				if (up) tick++;
				else tick--;
				
				if (tick >= limit && up) up = false;
				//System.out.println(tick+"/"+limit+" : "+up);
			}
		};
	}

	private Vec2 getPosition() {
		return body.getPosition();
	}

	private float getAngle() {
		return body.getAngle();
	}
	
	private BodyDef getBodyDef() {
		return bdef;
	}
	
	private void setBody (Body b) {
		body = b;
	}
	
	private Body getBody() {
		return body;
	}
	
	private FixtureDef getFixtureDef() {
		return fdef;
	}
	
	private ArrayList<CircleShape> getShapes() {
		return shapes;
	}
	
	public static Ship3 createInWorld(GameWorld world, float x, float y) throws ShipCreationException {
		Ship3 act = new Ship3(x, y);
		act.setBody(world.addActor(act, act.getBodyDef()));
		for (Shape s : act.getShapes()) {
			act.getFixtureDef().shape = s;
			act.getBody().createFixture(act.getFixtureDef());
		}
		return act;
	}

	@Override
	public WorldPainter getPainter() {
		return structPainter;
	}

	@Override
	public Behavior getBehavior() {
		return step;
	}

	@Override
	public void gestureReceived(Gesture g) {
		if (g.getType() != Type.LINE) return;
		step = LinearMove.createOnBody(body, g.getDirection(), g.getValue());
	}
}